package diseaseParser;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import parser.DBFParserException;
import parser.FileListing;
import entities.DiseaseOccurrence;

public class Main2 {
	
	EntityManagerFactory factory = Persistence.createEntityManagerFactory("medic_base");
	EntityManager em = factory.createEntityManager();
	public int overallCounter = 0;
	public int someOtherCounter = 0;
	
	
	public static void main(String[] args){
		Main2 d = new Main2();
		d.parseFiles("C:\\teste2");

	}
	
	private void parseFiles(String directory){
		File dir = new File(directory);
		ArrayList<File> files = new ArrayList<File>();
		try {
			files = new FileListing().listFiles(dir);

		} catch (DBFParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			
			if(files.size() != 0) {
				for (File file : files) {
					parseFile(file);
				}
			}
		} catch(Exception e) {
			e.printStackTrace();
		}

	}
	
	private void parseFile(File file) {
				

		if(file.exists()){
			FileStructure f = FileStructure.getInstance(getFileType(file));
			InputStream is = null;
			try{
				is = new FileInputStream(file);
			} catch(Exception e) {
				e.printStackTrace();
			}
			
			byte[] firstHeader = new byte[32];
			try {
				is.read(firstHeader, 0, 32);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			int firstDataRecord = noComplement(firstHeader[8]) + noComplement(firstHeader[9]) * 256;
			int lengthDataRecord = noComplement(firstHeader[10]) + noComplement(firstHeader[11]) * 256;
						
			System.out.println("first: " + firstDataRecord + " length: " + lengthDataRecord);
			byte[] secondHeader = new byte[firstDataRecord - 32];
			try{
				is.read(secondHeader, 0, firstDataRecord - 32);
			} catch (IOException e){
				e.printStackTrace();
			}

			byte[] row = new byte[lengthDataRecord];
			
			// Entity variables
			
			boolean reading = true;
			
			try{
				em.getTransaction().begin();
				while(reading) {
					String otherDisease = "";
					
					int bytesRead = is.read(row, 0, lengthDataRecord);
					if(bytesRead < lengthDataRecord)
						break;
					if(row[0] == 0x20){
						
						Pattern p = Pattern.compile("J");
						String primaryDisease = stringFromBytes(row, f.primaryDisease[0], f.primaryDisease[1]);
						String secondaryDisease = stringFromBytes(row, f.secondaryDisease[0], f.secondaryDisease[1]);
						Matcher m = p.matcher(primaryDisease);
						Matcher m2 = p.matcher(secondaryDisease);
						
						boolean mFound = m.find();
						boolean m2Found = m2.find();
						boolean patternFound = mFound || m2Found;
						
						if (patternFound) {
							DiseaseOccurrence disOc = new DiseaseOccurrence();
							disOc.setOccurrenceDate(dateFromBytes(row, f.occurrenceDate[0], f.occurrenceDate[1]));
							disOc.setCpf(stringFromBytes(row, f.cpf[0], f.cpf[1]));
							disOc.setBirthProvince(stringFromBytes(row, f.birthProvince[0], f.birthProvince[1]));
							disOc.setZipCode(stringFromBytes(row, f.zipCode[0], f.zipCode[1]));
							disOc.setBirthday(dateFromBytes(row, f.birthday[0], f.birthday[1]));
							disOc.setGender(stringFromBytes(row, f.gender[0], f.gender[1]));
							
							if(mFound){						
								disOc.setDisease(primaryDisease);
							} else if(m2Found){
								disOc.setDisease(secondaryDisease);
							}
							
							
							em.persist(disOc);
							
							System.out.println("occurrenceDate: " + disOc.getOccurrenceDate().toString() + " Cpf:" + disOc.getCpf() + " birhPlace: " + disOc.getBirthProvince() + " zipCode: " + disOc.getZipCode()
									+ " birthday: " + disOc.getBirthday().toString() + " gender: " + disOc.getGender() + " disease: " + disOc.getDisease() + " secondDisease: " + otherDisease);
						}
						// System.out.println("m1: " + m.toString() + " m2: " + m2.toString());
						
					}
					overallCounter++;
					someOtherCounter++;
				}
				em.getTransaction().commit();
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			
			
			

			
		}
		System.out.println(file.toString() + " overallCounter: " + overallCounter + " diseasesFound:" + someOtherCounter);
		someOtherCounter = 0;
		
	}
	
	private String getFileType(File file){
		return file.getName().substring(0, 2);
	}
	
	private int noComplement(int anyNumber){
		if(anyNumber < 0)
			return 256 + anyNumber;
		else 
			return anyNumber;
	}
	
	private Date dateFromBytes(byte[] row, int initial, int end){
		String dateStr = stringFromBytes(row, initial, end);
		
		Calendar c = Calendar.getInstance();
		c.clear();
		if(dateStr.length() >= 8)
			c.set(Integer.valueOf(dateStr.substring(0, 4)), 
				  Integer.valueOf(dateStr.substring(4, 6)) - 1,
				  Integer.valueOf(dateStr.substring(6, 8)));
		else if(dateStr.length() >= 6)
			c.set(Integer.valueOf(dateStr.substring(0, 4)), 
				  Integer.valueOf(dateStr.substring(4, 6)) - 1, 1);
		else
			return null;

		return c.getTime();
	}
	
	private String stringFromBytes(byte[] row, int initial, int end) {
		String result = "";
		if(row.length < end)
			return "";
		for (int i = initial; i <= end; i++) {
			result += new Character((char) row[i]);
		}
		return result;
	}
}
